package com.flowable.project.service.impl;

import com.flowable.project.common.ErrorCode;
import com.flowable.project.common.SendHttp;
import com.flowable.project.mapper.OpenApiInfoMapper;
import com.flowable.project.mapper.PathInfoMapper;
import com.flowable.project.model.OpenApiInfo;
import com.flowable.project.model.ParamsInfo;
import com.flowable.project.model.request.SendHttpModel;
import com.flowable.project.service.OpenApiService;
import com.flowable.project.util.JsonData;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class OpenApiServiceImpl implements OpenApiService {
    @Autowired
    private OpenApiInfoMapper openApiInfoMapper;

    @Autowired
    private PathInfoMapper pathInfoMapper;

    /**
         * @Author zjl
         * @Description //保存openApi文件到数据库
         * @Date 21:22 2021/11/17
         * @Param [filename]
         * @return void
         **/

    @Override
    public void saveOpenApiInfo(String filename) {
        SwaggerParseResult result = new OpenAPIParser().readLocation(filename, null, null);
        OpenAPI openAPI = result.getOpenAPI();
        String preUrl = openAPI.getServers().get(0).getUrl();
        Set<String> keys = openAPI.getPaths().keySet();
        for(String key:keys){
            PathItem pathItem = openAPI.getPaths().get(key);
            Operation operation = new Operation();
            if (pathItem.getGet() != null){
                operation = pathItem.getGet();
                saveGet(preUrl+key,operation);
            }if (pathItem.getPost() != null){
                operation = pathItem.getPost();
                savePost(preUrl+key,operation,openAPI);
            }if (pathItem.getPut() != null){
                operation = pathItem.getPut();
            }if (pathItem.getDelete() != null){
                operation = pathItem.getDelete();
            }

        }
    }

    /**
         * @Author zjl
         * @Description 判断发送http请求的类型
         * @Date 21:22 2021/11/17
         * @Param [sendHttpModel]
         * @return void
         **/

    @Override
    public  JsonData sendHttp(SendHttpModel sendHttpModel) {
        OpenApiInfo openApiInfo = openApiInfoMapper.findDetailById(sendHttpModel.getUrlId());
        if(!sendHttpModel.getHttpType().equals(openApiInfo.getType())){
            return JsonData.buildError("请求类型错误", ErrorCode.REQUEST_TYPE_ERROR);
        }
        if("GET".equals(sendHttpModel.getHttpType())){
            return SendHttp.sendGet(sendHttpModel.getData(),openApiInfo);
        }else if("POST".equals(sendHttpModel.getHttpType())){
            return SendHttp.sendPost(sendHttpModel.getData(),openApiInfo);
        }
        return JsonData.buildSuccess();
    }

    /**
         * @Author zjl
         * @Description 保存get请求
         * @Date 19:56 2021/11/19
         * @Param [preUrl, operation]
         * @return void
         **/

    public void saveGet(String preUrl, Operation operation){
        OpenApiInfo openApiInfo = new OpenApiInfo();
        openApiInfo.setPathUrl(preUrl);
        openApiInfo.setType("GET");
        openApiInfo.setOperationId(operation.getOperationId());
        openApiInfoMapper.insert(openApiInfo);
        if(operation.getParameters()!=null) {
            List<Parameter> list = operation.getParameters();
            for (Parameter l : list) {
                ParamsInfo pathInfo = new ParamsInfo();
                if(l.getRequired()){
                    pathInfo.setIsRequire(1);
                }else{
                    pathInfo.setIsRequire(0);
                }
                pathInfo.setOpenApiId(openApiInfo.getId());
                pathInfo.setName(l.getName());
                if("query".equals(l.getIn())){
                    pathInfo.setIsBody(0);
                }else{
                    pathInfo.setIsBody(1);
                }
                pathInfo.setType(l.getSchema().getType());
                pathInfoMapper.insert(pathInfo);
            }
        }
    }

    /**
         * @Author zjl
         * @Description 保存post请求
         * @Date 19:56 2021/11/19
         * @Param [preUrl, operation, openAPI]
         * @return void
         **/

    public void savePost(String preUrl,Operation operation,OpenAPI openAPI){
        OpenApiInfo openApiInfo = new OpenApiInfo();
        openApiInfo.setPathUrl(preUrl);
        openApiInfo.setType("POST");
        openApiInfo.setOperationId(operation.getOperationId());
        openApiInfoMapper.insert(openApiInfo);
        if(operation.getParameters()!=null) {
            List<Parameter> list = operation.getParameters();
            for (Parameter l : list) {
                ParamsInfo pathInfo = new ParamsInfo();
                if(l.getRequired()){
                    pathInfo.setIsRequire(1);
                }else{
                    pathInfo.setIsRequire(0);
                }
                pathInfo.setOpenApiId(openApiInfo.getId());
                pathInfo.setName(l.getName());
                if("query".equals(l.getIn())){
                    pathInfo.setIsBody(0);
                }else{
                    pathInfo.setIsBody(1);
                }
                pathInfo.setType(l.getSchema().getType());
                pathInfoMapper.insert(pathInfo);
            }
        }
        if(operation.getRequestBody()!=null){
            String ref = operation.getRequestBody().getContent().get("application/json").getSchema().get$ref();
            String[] split = ref.split("/");
            Schema schema = openAPI.getComponents().getSchemas().get(split[split.length - 1]);
            Map<String,Schema> properties = schema.getProperties();
            for(String key:properties.keySet()){
                ParamsInfo pathInfo = new ParamsInfo();
                pathInfo.setOpenApiId(openApiInfo.getId());
                pathInfo.setType(properties.get(key).getType());
                pathInfo.setName(key);
                pathInfo.setIsBody(1);
                pathInfoMapper.insert(pathInfo);
            }
        }
    }
}
